added samples
[windows-sources.git] / sdk / samples / all in on code / Visual Studio 2010 / CSManipulateImagesInWordDocument / WordDocumentImageManipulator.cs
blob64f99d0f35ff16388c1328efb259f55f6886e0e4
1 /****************************** Module Header ******************************\
2 Module Name: WordDocumentImageManipulator.cs
3 Project: CSManipulateImagesInWordDocument
4 Copyright (c) Microsoft Corporation.
6 The class WordDocumentImageManipulator is used to export, delete or replace
7 the images in a word document.
9 The image data in a document are stored as a ImagePart, and the Blip element
10 in a Drawing element will refers to the ImagePart. Different Blip elements may
11 refer to the same ImagePart.
13 To delete/replace the images in a document, we need to edit the Blip/Drawing
14 element.
17 This source is subject to the Microsoft Public License.
18 See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
19 All other rights reserved.
21 THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
22 EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
23 WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
24 \***************************************************************************/
26 using System;
27 using System.Collections.Generic;
28 using System.Drawing;
29 using System.IO;
30 using System.Linq;
31 using DocumentFormat.OpenXml;
32 using DocumentFormat.OpenXml.Drawing;
33 using DocumentFormat.OpenXml.Packaging;
34 using DocumentFormat.OpenXml.Wordprocessing;
36 namespace CSManipulateImagesInWordDocument
38 public class WordDocumentImageManipulator : IDisposable
40 bool disposed = false;
42 // Occured when an image is deleted or replaced.
43 public event EventHandler ImagesChanged;
45 // The WordprocessingDocument instance.
46 public WordprocessingDocument Document { get; private set; }
48 /// <summary>
49 /// Initialize the WordDocumentImageManipulator instance.
50 /// </summary>
51 /// <param name="path">
52 /// The document file path.
53 /// </param>
54 public WordDocumentImageManipulator(FileInfo path)
57 // Open the document as editable.
58 Document = WordprocessingDocument.Open(path.FullName, true);
62 /// <summary>
63 /// Get all images in the documents.
64 /// The image in a document is stored as a Blip element.
65 /// </summary>
66 /// <returns></returns>
67 public IEnumerable<Blip> GetAllImages()
70 // Get the drawing elements in the document.
71 var drawingElements = from run in Document.MainDocumentPart.Document.Descendants<DocumentFormat.OpenXml.Wordprocessing.Run>()
72 where run.Descendants<Drawing>().Count() != 0
73 select run.Descendants<Drawing>().First();
75 // Get the blip elements in the drawing elements.
76 var blipElements = from drawing in drawingElements
77 where drawing.Descendants<Blip>().Count() > 0
78 select drawing.Descendants<Blip>().First();
80 return blipElements;
83 /// <summary>
84 /// Get the image from the Blip element.
85 /// </summary>
86 public Image GetImageInBlip(Blip blipElement)
89 // Get the ImagePart referred by the Blip element.
90 var imagePart = Document.MainDocumentPart.GetPartById(blipElement.Embed.Value)
91 as ImagePart;
93 if (imagePart != null)
95 using (Stream imageStream = imagePart.GetStream())
97 Bitmap img = new Bitmap(imageStream);
98 return img;
101 else
103 throw new ApplicationException("Can not find image part : "
104 + blipElement.Embed.Value);
108 /// <summary>
109 /// Delete the Drawing element that contains the Blip element.
110 /// </summary>
111 /// <param name="blipElement"></param>
112 public void DeleteImage(Blip blipElement)
114 OpenXmlElement parent = blipElement.Parent;
115 while (parent != null &&
116 !(parent is DocumentFormat.OpenXml.Wordprocessing.Drawing))
118 parent = parent.Parent;
121 if (parent != null)
123 Drawing drawing = parent as Drawing;
124 drawing.Parent.RemoveChild<Drawing>(drawing);
126 // Raise the ImagesChanged event.
127 this.OnImagesChanged();
132 /// <summary>
133 /// To replace an image in a document
134 /// 1. Add an ImagePart to the document.
135 /// 2. Edit the Blip element to refer to the new ImagePart.
136 /// </summary>
137 /// <param name="blipElement"></param>
138 /// <param name="newImg"></param>
139 public void ReplaceImage(Blip blipElement, FileInfo newImg)
141 string rid = AddImagePart(newImg);
142 blipElement.Embed.Value = rid;
143 this.OnImagesChanged();
146 /// <summary>
147 /// Add ImagePart to the document.
148 /// </summary>
149 string AddImagePart(FileInfo newImg)
151 ImagePartType type = ImagePartType.Bmp ;
152 switch(newImg.Extension.ToLower())
154 case ".jpeg":
155 case ".jpg":
156 type = ImagePartType.Jpeg;
157 break;
158 case ".png":
159 type = ImagePartType.Png;
160 break;
161 default:
162 type = ImagePartType.Bmp;
163 break;
166 ImagePart newImgPart = Document.MainDocumentPart.AddImagePart(type);
167 using (FileStream stream = newImg.OpenRead())
169 newImgPart.FeedData(stream);
172 string rId = Document.MainDocumentPart.GetIdOfPart(newImgPart);
173 return rId;
177 /// <summary>
178 /// Raise the ImagesChanged event.
179 /// </summary>
180 protected virtual void OnImagesChanged()
182 if (this.ImagesChanged != null)
184 this.ImagesChanged(this, EventArgs.Empty);
188 public void Dispose()
190 Dispose(true);
191 GC.SuppressFinalize(this);
194 protected virtual void Dispose(bool disposing)
196 // Protect from being called multiple times.
197 if (disposed)
199 return;
202 if (disposing)
204 if (Document != null)
206 Document.Dispose();
208 disposed = true;